import type {CSSProperties} from 'vue'
import {useNavTabsStore} from '@/stores/modules/navTabs.store'
import {useWebConfigStore} from '@/stores/modules/webConfig.store'
import {toSafeInteger} from 'lodash-es'
import {Session} from '@/utils/storageUtil'
import {cacheKeys} from '@/stores/constant/cacheKey'

/**
 * main高度
 * @param extra main高度额外减去的px数,可以实现隐藏原有的滚动条
 * @return CSSProperties
 */
export function mainHeightStyle(extra: number = 0): CSSProperties {
	let height = extra
	const adminLayoutMainExtraHeight: Record<LayoutConfig['layoutMode'], number> = {
		Default: 70,
		Classic: 50,
		Streamline: 60
	}
	const webConfigStore = useWebConfigStore()
	if (!useNavTabsStore().tabFullScreen) {
		height += adminLayoutMainExtraHeight[webConfigStore.layout.layoutMode]
	}
	return {
		height: 'calc(100vh - ' + height.toString() + 'px)'
	}
}

/**
 * 计算元素的最大高度，以让元素填充整个页面，同时不出现垂直滚动条
 * @param elementSelectors 目标元素上方和下方元素的选择器
 * @return number
 */
export const calcMaxHeight = (...elementSelectors: string[]): number => {
	return calcMaxHeightWithExtra(0, ...elementSelectors)
}

/**
 * 计算元素的最大高度，以让元素填充整个页面，同时不出现垂直滚动条<br/>
 * 当页面存在某些组件比如el-card时，需要额外的高度，请自行测试额外高度的值
 * @param extraHeight 额外高度
 * @param elementSelectors 目标元素上方和下方元素的选择器
 * @return number
 */
export const calcMaxHeightWithExtra = (extraHeight: number, ...elementSelectors: string[]): number => {
	const mainHeight = getMainHeight()
	let extra: number = 0
	if (extraHeight !== 0) {
		extra += extraHeight
	}
	for (const elementId of elementSelectors) {
		const element = document.querySelector(elementId)
		if (element) {
			const computedStyle: CSSStyleDeclaration = window.getComputedStyle(element)
			extra += getPxNumber(computedStyle.height)
			extra += handleMargin(computedStyle.margin)
		}
	}
	return toSafeInteger(mainHeight - extra)
}

export const getMainHeight = () => {
	// 获取窗口高度
	let mainHeight: number = 0
	if (window.innerHeight) {
		mainHeight = window.innerHeight
	} else if ((document.body) && (document.body.clientHeight)) {
		mainHeight = document.body.clientHeight
	} else if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {
		mainHeight = document.documentElement.clientHeight
	} else {
		console.warn('calcMaxHeight(): 无法获取窗口高度')
		return 800
	}
	let extra: number = 0
	// 为了不触发垂直滚动条，需要额外的26px
	extra += 26
	// .default-main的margin-top: 16px
	extra += 16
	// .default-main的margin-bottom: 16px
	extra += 16
	const webConfigStore = useWebConfigStore()
	switch (webConfigStore.layout.layoutMode) {
		case 'Default':
			extra += 70
			break
		case 'Classic':
			extra += 50
			break
		case 'Streamline':
			extra += 60
			break
	}
	return toSafeInteger(mainHeight - extra)
}

const getPxNumber = (height: string): number => {
	if (!height.endsWith('px')) {
		return 0
	}
	return Number(height.substring(0, height.length - 2))
}

const handleMargin = (margin: string): number => {
	const split = margin.split(' ')
	if (split.length === 1) {
		return getPxNumber(split[0]) * 2
	} else if (split.length === 2) {
		return getPxNumber(split[0])
	} else if (split.length === 3 || split.length === 4) {
		return getPxNumber(split[0]) + getPxNumber(split[2])
	} else {
		console.warn('handleMargin(): margin参数错误')
		return 0
	}
}

export const onAdaptiveLayout = () => {
	const webConfigStore = useWebConfigStore()
	const defaultBeforeResizeLayout = {
		layoutMode: webConfigStore.layout.layoutMode,
		menuCollapse: webConfigStore.layout.menuCollapse
	}
	const beforeResizeLayout = Session.get(cacheKeys.BEFORE_RESIZE_LAYOUT)
	if (!beforeResizeLayout) {
		Session.set(cacheKeys.BEFORE_RESIZE_LAYOUT, defaultBeforeResizeLayout)
	}
	const clientWidth = document.body.clientWidth
	// 小屏设备只能选择经典布局
	if (clientWidth < 1024) {
		webConfigStore.setLayout('menuCollapse', true)
		webConfigStore.setLayout('shrink', true)
		webConfigStore.layout.layoutMode = 'Classic'
	} else {
		let beforeResizeLayoutTemp = beforeResizeLayout || defaultBeforeResizeLayout
		webConfigStore.setLayout('menuCollapse', beforeResizeLayoutTemp.menuCollapse)
		webConfigStore.setLayout('shrink', false)
		webConfigStore.layout.layoutMode = beforeResizeLayoutTemp.layoutMode
	}
}
